package com.sunday.common.core.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 关键字判定
 *
 * @author zsy
 * @since 2022/10/11
 */
@Slf4j
public class KeywordUtils {

    /**
     * 直接禁止的
     */
    private static HashMap<String, Object> keysMap = new HashMap();

    private static int matchType = 1; // 1:最小长度匹配 2：最大长度匹配

    /**
     * 初始化关键字
     *
     * @param keywords
     */
    public static void init(List<String> keywords) {

        HashMap tempMap = new HashMap();
        if (keywords == null || keywords.isEmpty()) {
            log.info("keywords is empty");
            return;
        }
        for (int i = 0; i < keywords.size(); i++) {
            String key = keywords.get(i).trim();
            HashMap nowhash = tempMap;
            for (int j = 0; j < key.length(); j++) {
                char word = key.charAt(j);
                Object wordMap = nowhash.get(word);
                if (wordMap != null) {
                    nowhash = (HashMap) wordMap;
                } else {
                    HashMap<String, String> newWordHash = new HashMap<>();
                    newWordHash.put("isEnd", "0");
                    nowhash.put(word, newWordHash);
                    nowhash = newWordHash;
                }
                if (j == key.length() - 1) {
                    nowhash.put("isEnd", "1");
                }
            }
        }
        keysMap = tempMap;
    }

    /**
     * 检索内容中的关键字位置
     * 检查一个字符串从begin位置起开始是否有keyword符合， 如果有符合的keyword值，返回值为匹配keyword的长度，否则返回零
     *
     * @param txt
     * @param begin
     * @param flag  1:最小长度匹配 2：最大长度匹配
     * @return {@link int}
     */
    private static int checkKeyWords(String txt, int begin, int flag) {
        HashMap<String, Object> nowhash = null;
        nowhash = keysMap;
        int maxMatchRes = 0;
        int res = 0;
        int l = txt.length();
        char word = 0;
        for (int i = begin; i < l; i++) {
            word = txt.charAt(i);
            Object wordMap = nowhash.get(word);
            if (wordMap != null) {
                res++;
                nowhash = (HashMap) wordMap;
                if (((String) nowhash.get("isEnd")).equals("1")) {
                    if (flag == 1) {
                        wordMap = null;
                        nowhash = null;
                        txt = null;
                        return res;
                    } else {
                        maxMatchRes = res;
                    }
                }
            } else {
                txt = null;
                nowhash = null;
                return maxMatchRes;
            }
        }
        txt = null;
        nowhash = null;
        return maxMatchRes;
    }

    /**
     * 仅判断txt中是否有关键字
     *
     * @param txt
     * @return {@link boolean}
     */
    public static boolean isContainsKeyWords(String txt) {
        if (StringUtils.isBlank(txt)) {
            return false;
        }
        for (int i = 0; i < txt.length(); i++) {
            int len = checkKeyWords(txt, i, matchType);
            if (len > 0) {
                log.info("keywords: {}", txt.substring(i, i + len));
                return true;
            }
        }
        return false;
    }

    /**
     * 判断txt中是否有关键字, 并将关键字返回
     *
     * @param txt
     * @return {@link String}
     */
    public static String isContainsReturnKeyWords(String txt) {
        if (StringUtils.isBlank(txt)) {
            return null;
        }
        for (int i = 0; i < txt.length(); i++) {
            int len = checkKeyWords(txt, i, matchType);
            if (len > 0) {
                txt = txt.substring(i, i + len);
                log.info("keywords: {}", txt);
                return txt;
            }
        }
        return null;
    }

    /**
     * 返回txt中关键字的列表
     *
     * @param txt
     * @return {@link Set< String>}
     */
    public static Set<String> getTxtKeyWords(String txt) {
        Set set = new HashSet();
        if (StringUtils.isBlank(txt)) {
            return set;
        }
        for (int i = 0; i < txt.length(); ) {
            int len = checkKeyWords(txt, i, matchType);
            if (len > 0) {
                set.add(txt.substring(i, i + len));
                i += len;
            } else {
                i++;
            }
        }
        if (!set.isEmpty()) {
            log.info("keywords: {}", set);
        }
        return set;
    }

    /**
     * 返回关键字缓存
     *
     * @return {@link HashMap< String, Object>}
     */
    public static HashMap<String, Object> getKeysMap() {
        return keysMap;
    }

}
